using System;
using System.Collections.Generic;
using Castle.DynamicProxy;
using FluentIoC.Helpers;
using FluentIoC.Interfaces;

namespace FluentIoC.Configuration.Commands
{
    public class RegisterFactory : IRegistration
    {
        public Type FactoryType { get; set; }
        public string Key { get; set; }
        public string CreateMethod { get; set; }
        public Dictionary<Type, string> Services
        {
            get { return new Dictionary<Type, string>(); }
        }

        public RegisterFactory(Type service, string key)
            :this(service, key, string.Empty)
        {
        }

        public RegisterFactory(Type service, string key, string createMethod)
        {
            FactoryType = service;
            Key = key;
            CreateMethod = createMethod;
        }

        public void Configure(IIoCConfiguration config, Dictionary<Type, string> services)
        {
            config.RegisterFactory(Key, FactoryType);
        }

        public bool IsValid(IConventions conventions)
        {
            if(false == conventions.IsValidType(FactoryType))
            {
                Debug.FilteredInvalidType(FactoryType, ConventionInvalidReason.InvalidType);

                return false;
            }

            if(false == conventions.IsValidFactoryType(FactoryType))
            {
                Debug.FilteredInvalidType(FactoryType, ConventionInvalidReason.InvalidFactory);

                return false;
            }

            return true;
        }
    }

    public class RegisterFactory<T> : RegisterFactory
    {
        protected ProxyGenerator _proxyGenerator = new ProxyGenerator();

        public RegisterFactory(Func<T, object> createMethod)
            :this(createMethod, typeof(T).GetDefaultKey())
        {
        }

        public RegisterFactory(Func<T, object> createMethod, string key)
            :base(typeof(T), key, createMethod.GetMethodName())
        {
        }
    }
}